package com.tpvlog.im.gateway.tcp;

import com.tpvlog.im.common.Constants;
import com.tpvlog.im.common.Message;
import com.tpvlog.im.common.Request;
import com.tpvlog.im.common.Response;
import com.tpvlog.im.gateway.tcp.common.RequestHandler;
import com.tpvlog.im.gateway.tcp.common.SessionManager;
import com.tpvlog.im.protocal.AuthenticateRequestProto;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.socket.SocketChannel;

/**
 * 客户端请求处理器
 */
public class GatewayTcpHandler extends ChannelInboundHandlerAdapter {

    /**
     * 与客户端建立连接
     *
     * @param ctx
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        System.out.println("已经跟客户端建立连接，客户端地址为：" + ctx.channel());
    }

    /**
     * 与客户端断开连接
     *
     * @param ctx
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        // 删除缓存的客户端连接
        SocketChannel socketChannel = (SocketChannel) ctx.channel();
        SessionManager.getInstance().removeSession(socketChannel);
        System.out.println("检测到客户端的连接断开，删除其连接缓存：" + socketChannel.remoteAddress().toString());
    }

    /**
     * 处理客户端请求
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buffer = (ByteBuf) msg;
        Message message = new Message(buffer);
        System.out.println("收到一个消息，消息类型为：" + message.getMessageType());
        // 1.如果是SDK客户端的请求
        if (message.getMessageType() == Constants.MESSAGE_TYPE_REQUEST) {
            Request request = message.toRequest();
            // 认证
            if (request.getRequestType() == Constants.REQUEST_TYPE_AUTHENTICATE) {
                AuthenticateRequestProto.AuthenticateRequest authenticateRequest =
                        AuthenticateRequestProto.AuthenticateRequest.parseFrom(request.getBody());
                System.out.println("收到SDK客户端发送过来的认证请求：" + authenticateRequest);
                // 交给请求Hander组件进行处理
                RequestHandler.getInstance().authenticate(authenticateRequest);
            }
            // 单聊
            else if (request.getRequestType() == Constants.REQUEST_TYPE_SEND_MESSAGE) {
                System.out.println("接收到客户端发送过来的单聊消息......");
                request = new Request(
                        request.getAppSdkVersion(),
                        request.getRequestType(),
                        request.getSequence(),
                        request.getBody());
                RequestHandler.getInstance().sendMessage(request);
            }
        }
        // 2.如果是SDK客户端的响应
        else if (message.getMessageType() == Constants.MESSAGE_TYPE_RESPONSE) {
            Response response = message.toResponse();
            if (response.getRequestType() == Constants.REQUEST_TYPE_PUSH_MESSAGE) {
                System.out.println("接收到客户端返回的消息推送响应......");
                response = new Response(response, response.getBody());
                RequestHandler.getInstance().pushMessageResponse(response);
            }
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
